﻿using System.ComponentModel;
using System.Reflection;

using DevExpress.Entity.ProjectModel;

using Kuiper.Core.EditorAttributes;

using ReaLTaiizor.Controls;

namespace Kuiper.WinUI;

public static class FormBuilder
{
	public static void Create(Type targetObject, HopeTabPage parent)
	{
		try
		{
			var groupedProperties = GetPropertyGroups(targetObject);

			parent.TabPages.Clear();

			foreach (var groupedProperty in groupedProperties)
			{
				var groupPage = new System.Windows.Forms.TabPage();
				groupPage.Text = groupedProperty.Key;

				var tableLayout = new System.Windows.Forms.TableLayoutPanel();
				tableLayout.Dock = DockStyle.Top;

				FillPropertiesInLayout(tableLayout, groupedProperty.Value);

				groupPage.Controls.Add(tableLayout);
				parent.TabPages.Add(groupPage);
			}
		}
		catch (Exception e)
		{
			Console.WriteLine(e);
		}
	}

	private static Dictionary<string, List<PropertyInfo>> GetPropertyGroups(Type targetObject)
	{
		const string DefaultGroupName = "Detail";

		var groupedProperties = new Dictionary<string, List<PropertyInfo>>();
		var properties = targetObject.GetProperties();

		foreach (var property in properties)
		{
			// Ignore propety whose browsable attribute is false
			var browsableAttribute = property.GetCustomAttribute<BrowsableAttribute>();

			if (browsableAttribute?.Browsable == false) continue;

			var groupAttribute = property.GetCustomAttribute<TabSlotAttribute>();

			if(groupAttribute != null)
			{
				if (groupedProperties.ContainsKey(groupAttribute.SlotName))
				{
					groupedProperties[groupAttribute.SlotName].Add(property);
				}
				else
				{
					groupedProperties.Add(groupAttribute.SlotName, new List<PropertyInfo>() { property });
				}
			}
			else
			{
				if(!groupedProperties.ContainsKey(DefaultGroupName))
				{
					groupedProperties.Add(DefaultGroupName, new List<PropertyInfo>());
				}

				groupedProperties[DefaultGroupName].Add(property);
			}
		}

		return groupedProperties;
	}

	private static void FillPropertiesInLayout(TableLayoutPanel layoutPanel, List<PropertyInfo> properties)
	{
		layoutPanel.ColumnCount = GetMaxLayoutColumnCount(properties);
		layoutPanel.RowCount = (int)Math.Ceiling( properties.Count / Convert.ToDouble(layoutPanel.ColumnCount));

		layoutPanel.ColumnStyles.Clear();
		for (int columnIndex = 0; columnIndex < layoutPanel.ColumnCount; columnIndex++)
		{
			layoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100 / layoutPanel.ColumnCount));
		}

		layoutPanel.RowStyles.Clear();
		for(int rowIndex = 0;  rowIndex < layoutPanel.RowCount; rowIndex++)
		{
			layoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
		}

		layoutPanel.Height = 42 * layoutPanel.RowCount;

		foreach (var property in properties)
		{
			var propertyEditor = new PropertyEditor();
			propertyEditor.Height = 40;
			propertyEditor.BindingProperty = property;
			propertyEditor.Anchor = AnchorStyles.Left | AnchorStyles.Right;
			layoutPanel.Controls.Add(propertyEditor);
		}

		layoutPanel.ResumeLayout(true);
	}

	private static int GetMaxLayoutColumnCount(List<PropertyInfo> properties)
	{
		var maxColumnWidth = 2;

		foreach (var property in properties)
		{
			var thirdWidthAttribue = property.GetCustomAttribute<ThirdWidthAttribute>();
			if (thirdWidthAttribue != null) maxColumnWidth = Math.Max(maxColumnWidth, 3);

			var quaterWidthAttribue = property.GetCustomAttribute<QuarterWidthAttribute>();
			if (quaterWidthAttribue != null) maxColumnWidth = Math.Max(maxColumnWidth, 4);
		}

		return maxColumnWidth;
	}

	public static void Create<TObject>(Control parent) where TObject : KPBaseObject, new()
	{

	}

	public static void BindingEditor<TObject>(Control editor, TObject targetObj) where TObject : KPBaseObject, new()
	{

	}

	public static void BindingEditor(Control editor, object targetObj)
	{

	}
}
